package com.nuanshui.heatedloan.extension.security;

import com.alibaba.dubbo.config.annotation.Reference;
import com.nuanshui.framework.springContext.SpringContextUtil;
import com.nuanshui.framework.utils.redis.JedisUtil;
import com.nuanshui.framework.utils.serializer.SerializationUtils;
import com.nuanshui.heatedloan.constant.GlobalParam;
import com.nuanshui.heatedloan.userinfo.facade.UserTokenService;
import com.nuanshui.heatedloan.userinfo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * Created by zxh on 2017/2/12.
 */
@Service
public class SecurityContextService {

    @Autowired
    private JedisUtil jedisUtil;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Reference(url= GlobalParam.USER_DUBBO_SERVER,timeout=GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.USER_DUBBO_SERVER_VERSION)
    private UserTokenService userTokenService;

    public void setAuthentication(User user)
    {
        setAuthentication(user,false);
    }

    public void setAuthenticationWithToken(final User user, final String token) {
        setAuthentication(user, false);
        createUserSession(token);

        taskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                userTokenService.delUserSafeToken(token, user.getId());
                userTokenService.saveUserSafeToken(token, user.getId());
            }
        });
    }

    public void setAuthentication(User user,boolean bPwd)
    {
        Authentication auth = new UsernamePasswordAuthenticationToken(user, bPwd ? user.getPassword() : null, user.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(auth);
    }

    public void clearAuth()
    {
        SecurityContextHolder.getContext().setAuthentication(null);
    }

    public User getCurrentUser()
    {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null) {
            Object principal = auth.getPrincipal();
            if (principal instanceof User) {
                User user = (User) principal;
                if (user != null && !user.isAnonymous() ) {
                    return user;
                }
            }
        }
        return null;
    }

    private static String sessionKey = "securit_context_";

    public void initContext() {
        SecurityContextHolder.setContext(new SecurityContextImpl());
    }

    public void setUserContext(String safeToken) throws IOException {
        SecurityContext securityContext = (SecurityContext) SerializationUtils.deserialize(jedisUtil.get((sessionKey + safeToken).getBytes()));
        if (securityContext != null) {
            SecurityContextHolder.setContext(securityContext);
        }
    }

    public void removeUserSession(String safeToken)
    {
        jedisUtil.del(sessionKey + safeToken);
    }

    public void createUserSession(String safeToken)
    {
        SecurityContext context = SecurityContextHolder.getContext();
        try {
            jedisUtil.set(sessionKey + safeToken, SerializationUtils.serialize(context));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
